
#include "CAnimationManager.h"
#include "CAnimation.h"
#include "CFrame.h"
#include "SGD Wrappers\tinyxml\tinyxml.h"
#include "SGD Wrappers\CSGD_TextureManager.h"
#define NULL 0

CAnimationManager* CAnimationManager::pInstance = NULL;

CAnimationManager::CAnimationManager()
{
}

CAnimationManager::~CAnimationManager()
{
}

CAnimationManager* CAnimationManager::GetInstance()
{
	if(!pInstance)
		pInstance = new CAnimationManager();
	return pInstance;
}

void CAnimationManager::DeleteInstance()
{
	if(pInstance)
	{
		delete pInstance;
		pInstance = NULL;
	}
}

RECT CAnimationManager::GetImageRect(AnimInfo* anim)
{
	return m_vAnimations[anim->GetCurAnim()]->GetFrames()[anim->GetCurFrame()]->GetImageRect();
}

RECT CAnimationManager::GetCollisionRect(AnimInfo* anim)
{
	return m_vAnimations[anim->GetCurAnim()]->GetFrames()[anim->GetCurFrame()]->GetCollisionRect();
}

RECT CAnimationManager::GetHitRect(AnimInfo* anim)
{
	return m_vAnimations[anim->GetCurAnim()]->GetFrames()[anim->GetCurFrame()]->GetHitRect();
}

POINT CAnimationManager::GetAnchorPoint(AnimInfo* anim)
{
	return m_vAnimations[anim->GetCurAnim()]->GetFrames()[anim->GetCurFrame()]->GetAnchorPoint();
}

vector<POINT*>& CAnimationManager::GetParticles(AnimInfo* anim)
{
	return m_vAnimations[anim->GetCurAnim()]->GetFrames()[anim->GetCurFrame()]->GetParticles();
}

void CAnimationManager::Render(AnimInfo* anim, int PosX, int PosY, float fScale, float fRotation, bool isPlayed, DWORD dwColor)
{
	m_vAnimations[anim->GetCurAnim()]->Render(anim->GetCurFrame(), PosX, PosY, fScale, fRotation, isPlayed, dwColor);
}

void CAnimationManager::FindAnim(string animID, AnimInfo* anim)
{
	if(m_vAnimations[anim->GetCurAnim()]->GetAnimationID() == animID)
		return;
	for(size_t i = 0; i < m_vAnimations.size(); i++)
	{
		if(animID == m_vAnimations[i]->GetAnimationID())
		{
			if(anim->GetCurAnim() != i)
			{
				anim->SetCurAnim(i);
				anim->SetCurFrame(0);
				anim->SetElapsedTime(0.0f);
			}
			return;
		}
	}
}

void CAnimationManager::RandomAnim(AnimInfo* anim)
{
	int randomanim = rand()%m_vAnimations.size()-1;
	if(randomanim < 0)
		randomanim = 0;
	for(size_t i = 0; i < m_vAnimations[randomanim]->GetFrames().size(); i++)
	{
		if(m_vAnimations[randomanim]->GetFrames()[i]->GetEvent() != "")
		{
			randomanim = 0;
			break;
		}
	}
	anim->SetCurAnim(randomanim);
	anim->SetCurFrame(0);
	anim->SetElapsedTime(0.0f);
}

void CAnimationManager::Update(AnimInfo* anim, float fElapsedTime)
{
	m_vAnimations[anim->GetCurAnim()]->Update(anim, fElapsedTime);
}

bool CAnimationManager::LoadAnim(const char* filepath)
{
	TiXmlDocument doc;	

	if(!doc.LoadFile(filepath))
		return false;

	TiXmlElement* pRoot = doc.RootElement();

	if(!pRoot)
		return false;

	TiXmlElement* pAnimations = pRoot->FirstChildElement();
	
	string temp = "resource\\lambda\\";
	temp += pRoot->Attribute("spritesheet");

	int imageid = CSGD_TextureManager::GetInstance()->LoadTexture(temp.c_str(), 0);

	if(pAnimations)
	{
		TiXmlElement* pAnimation = pAnimations->FirstChildElement();

		while(pAnimation)
		{
			CAnimation* a = new CAnimation;
			a->SetImageID(imageid);
			a->SetAnimationID(pAnimation->Attribute("animid"));
			a->SetTotalTime(0.0f);
			a->SetSpeed(1.0f);
			int temp;
			pAnimation->Attribute("animtype", &temp);
			if(temp == 0)
				a->SetAnimationType(ONCE);
			else
				a->SetAnimationType(LOOPING);

			TiXmlElement* pFrames = pAnimation->FirstChildElement();

			if(pFrames)
			{
				TiXmlElement* pFrame = pFrames->FirstChildElement();

				while(pFrame)
				{
					CFrame* f = new CFrame;
					double time = 0.0f;
					pFrame->Attribute("duration", &time);
					time /= 100;
					f->SetDuration((float)time);

					int x = -1;
					int y = -1;
					int width = -1;
					int height = -1;
					RECT rect;

					TiXmlElement* pImageRect = pFrame->FirstChildElement("imagerect");
					pImageRect->Attribute("x", &x);
					pImageRect->Attribute("y", &y);
					pImageRect->Attribute("width", &width);
					pImageRect->Attribute("height", &height);

					rect.left = x;
					rect.top = y;
					rect.right = rect.left+width;
					rect.bottom = rect.top+height;

					f->SetImageRect(rect);

					TiXmlElement* pAnchorPt = pFrame->FirstChildElement("anchorpt");
					pAnchorPt->Attribute("x", &x);
					pAnchorPt->Attribute("y", &y);

					POINT anchor;
					POINT p;

					anchor.x = x;
					anchor.y = y;
					p.x = -(f->GetImageRect().left - x);
					p.y = -(f->GetImageRect().top - y);
					f->SetAnchorPoint(p);
					f->SetRotationPoint(anchor);

					TiXmlElement* pHitRect = pFrame->FirstChildElement("hitrect");
					pHitRect->Attribute("x", &x);
					pHitRect->Attribute("y", &y);
					pHitRect->Attribute("width", &width);
					pHitRect->Attribute("height", &height);

					rect.left = (anchor.x - x);
					rect.top = (anchor.y - y);
					rect.right = rect.left+width;
					rect.bottom = rect.top+height;
					
					f->SetHitRect(rect);

					TiXmlElement* pCollisionRect = pFrame->FirstChildElement("collisionrect");
					pCollisionRect->Attribute("x", &x);
					pCollisionRect->Attribute("y", &y);
					pCollisionRect->Attribute("width", &width);
					pCollisionRect->Attribute("height", &height);

					rect.left = anchor.x - x;
					rect.top = anchor.y - y;
					rect.right = rect.left+width;
					rect.bottom = rect.top+height;

					f->SetCollisionRect(rect);

					TiXmlElement* pEvent = pFrame->FirstChildElement("event");
					if(pEvent->GetText() != NULL)
						f->SetAnimationTrigger(pEvent->GetText());
					else
						f->SetAnimationTrigger("");

					TiXmlElement* pParticles = pFrame->FirstChildElement("particlepoints");

					if(pParticles)
					{
						TiXmlElement* pParticle = pParticles->FirstChildElement();

						while(pParticle)
						{
							POINT* part = new POINT;
							
							pParticle->Attribute("x", &x);
							pParticle->Attribute("y", &y);

							part->x = (anchor.x - x);
							part->y = (anchor.y - y);
							f->GetParticles().push_back(part);

							pParticle = pParticle->NextSiblingElement();
						}
					}
					a->GetFrames().push_back(f);
					pFrame = pFrame->NextSiblingElement();
				}
			}
			m_vAnimations.push_back(a);
			pAnimation = pAnimation->NextSiblingElement();
		}
	}
	return true;
}

void CAnimationManager::AddAnimation(CAnimation* Anim)
{
	m_vAnimations.push_back(Anim);
}

void CAnimationManager::RemoveAnimation()
{
	m_vAnimations.pop_back();
}

void CAnimationManager::Shutdown()
{
	for(size_t i = 0; i < m_vAnimations.size(); i++)
	{
		for(size_t j = 0; j < m_vAnimations[i]->GetFrames().size(); j++)
		{
			for(size_t k = 0; k < m_vAnimations[i]->GetFrames()[j]->GetParticles().size(); k++)
			{
				delete m_vAnimations[i]->GetFrames()[j]->GetParticles()[k];
			}
			m_vAnimations[i]->GetFrames()[j]->GetParticles().clear();
			delete m_vAnimations[i]->GetFrames()[j];
		}
		m_vAnimations[i]->GetFrames().clear();
		delete m_vAnimations[i];
	}
	m_vAnimations.clear();
}